package com.godenwater.yanyu.utils;

import java.io.UnsupportedEncodingException;

public class ByteUtil {
	private static String hexStr = "0123456789ABCDEF";
	private static String[] binaryArray = { "0000", "0001", "0010", "0011",
			"0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
			"1100", "1101", "1110", "1111" };

	public static byte[] longToBytes(long n) {
		byte[] b = new byte[8];
		b[7] = (byte) (n & 0xff);
		b[6] = (byte) (n >> 8 & 0xff);
		b[5] = (byte) (n >> 16 & 0xff);
		b[4] = (byte) (n >> 24 & 0xff);
		b[3] = (byte) (n >> 32 & 0xff);
		b[2] = (byte) (n >> 40 & 0xff);
		b[1] = (byte) (n >> 48 & 0xff);
		b[0] = (byte) (n >> 56 & 0xff);
		return b;
	}

	public static void longToBytes(long n, byte[] array, int offset) {
		array[7 + offset] = (byte) (n & 0xff);
		array[6 + offset] = (byte) (n >> 8 & 0xff);
		array[5 + offset] = (byte) (n >> 16 & 0xff);
		array[4 + offset] = (byte) (n >> 24 & 0xff);
		array[3 + offset] = (byte) (n >> 32 & 0xff);
		array[2 + offset] = (byte) (n >> 40 & 0xff);
		array[1 + offset] = (byte) (n >> 48 & 0xff);
		array[0 + offset] = (byte) (n >> 56 & 0xff);
	}

	public static long bytesToLong(byte[] array) {
		return ((((long) array[0] & 0xff) << 56)
				| (((long) array[1] & 0xff) << 48)
				| (((long) array[2] & 0xff) << 40)
				| (((long) array[3] & 0xff) << 32)
				| (((long) array[4] & 0xff) << 24)
				| (((long) array[5] & 0xff) << 16)
				| (((long) array[6] & 0xff) << 8) | (((long) array[7] & 0xff) << 0));
	}

	public static long bytesToLong(byte[] array, int offset) {
		return ((((long) array[offset + 0] & 0xff) << 56)
				| (((long) array[offset + 1] & 0xff) << 48)
				| (((long) array[offset + 2] & 0xff) << 40)
				| (((long) array[offset + 3] & 0xff) << 32)
				| (((long) array[offset + 4] & 0xff) << 24)
				| (((long) array[offset + 5] & 0xff) << 16)
				| (((long) array[offset + 6] & 0xff) << 8) | (((long) array[offset + 7] & 0xff) << 0));
	}

	public static byte[] intToBytes(int n) {
		byte[] b = new byte[4];
		b[3] = (byte) (n & 0xff);
		b[2] = (byte) (n >> 8 & 0xff);
		b[1] = (byte) (n >> 16 & 0xff);
		b[0] = (byte) (n >> 24 & 0xff);
		return b;
	}

	public static void intToBytes(int n, byte[] array, int offset) {
		array[3 + offset] = (byte) (n & 0xff);
		array[2 + offset] = (byte) (n >> 8 & 0xff);
		array[1 + offset] = (byte) (n >> 16 & 0xff);
		array[offset] = (byte) (n >> 24 & 0xff);
	}

	public static int bytesToInt(byte b[]) {
		return b[3] & 0xff | (b[2] & 0xff) << 8 | (b[1] & 0xff) << 16
				| (b[0] & 0xff) << 24;
	}

	public static int bytesToInt(byte b[], int offset) {
		return b[offset + 3] & 0xff | (b[offset + 2] & 0xff) << 8
				| (b[offset + 1] & 0xff) << 16 | (b[offset] & 0xff) << 24;
	}

	public static byte[] uintToBytes(long n) {
		byte[] b = new byte[4];
		b[3] = (byte) (n & 0xff);
		b[2] = (byte) (n >> 8 & 0xff);
		b[1] = (byte) (n >> 16 & 0xff);
		b[0] = (byte) (n >> 24 & 0xff);

		return b;
	}

	public static void uintToBytes(long n, byte[] array, int offset) {
		array[3 + offset] = (byte) (n);
		array[2 + offset] = (byte) (n >> 8 & 0xff);
		array[1 + offset] = (byte) (n >> 16 & 0xff);
		array[offset] = (byte) (n >> 24 & 0xff);
	}

	public static long bytesToUint(byte[] array) {
		return ((long) (array[3] & 0xff)) | ((long) (array[2] & 0xff)) << 8
				| ((long) (array[1] & 0xff)) << 16
				| ((long) (array[0] & 0xff)) << 24;
	}

	public static long bytesToUint(byte[] array, int offset) {
		return ((long) (array[offset + 3] & 0xff))
				| ((long) (array[offset + 2] & 0xff)) << 8
				| ((long) (array[offset + 1] & 0xff)) << 16
				| ((long) (array[offset] & 0xff)) << 24;
	}

	public static byte[] shortToBytes(short n) {
		byte[] b = new byte[2];
		b[1] = (byte) (n & 0xff);
		b[0] = (byte) ((n >> 8) & 0xff);
		return b;
	}

	public static void shortToBytes(short n, byte[] array, int offset) {
		array[offset + 1] = (byte) (n & 0xff);
		array[offset] = (byte) ((n >> 8) & 0xff);
	}

	public static short bytesToShort(byte[] b) {
		return (short) (b[1] & 0xff | (b[0] & 0xff) << 8);
	}

	/**
	 * byte数组转换为无符号short整数
	 * 
	 * @param bytes
	 *            byte数组
	 * @return short整数
	 */
	public static int byte2ToUnsignedShort(byte[] bytes) {
		int high = bytes[0];
		int low = bytes[1];
		return (high << 8 & 0xFF00) | (low & 0xFF);
	}

	public static short bytesToShort(byte[] b, int offset) {
		return (short) (b[offset + 1] & 0xff | (b[offset] & 0xff) << 8);
	}

	public static byte[] ushortToBytes(int n) {
		byte[] b = new byte[2];
		b[1] = (byte) (n & 0xff);
		b[0] = (byte) ((n >> 8) & 0xff);
		return b;
	}

	public static void ushortToBytes(int n, byte[] array, int offset) {
		array[offset + 1] = (byte) (n & 0xff);
		array[offset] = (byte) ((n >> 8) & 0xff);
	}

	public static int bytesToUshort(byte b[]) {
		return b[1] & 0xff | (b[0] & 0xff) << 8;
	}

	public static int bytesToUshort(byte b[], int offset) {
		return b[offset + 1] & 0xff | (b[offset] & 0xff) << 8;
	}

	public static byte[] ubyteToBytes(int n) {
		byte[] b = new byte[1];
		b[0] = (byte) (n & 0xff);
		return b;
	}

	public static void ubyteToBytes(int n, byte[] array, int offset) {
		array[0] = (byte) (n & 0xff);
	}

	public static int bytesToUbyte(byte[] array) {
		return array[0] & 0xff;
	}

	public static int bytesToUbyte(byte[] array, int offset) {
		return array[offset] & 0xff;
	}

	/**
	 * 
	 * @param str
	 * @return 转换为二进制字符串
	 */
	public static String byte2Str(byte[] bArray) {

		String outStr = "";
		int pos = 0;
		for (byte b : bArray) {
			// 高四位
			pos = (b & 0xF0) >> 4;
			outStr += binaryArray[pos];
			// 低四位
			pos = b & 0x0F;
			outStr += binaryArray[pos];
		}
		return outStr;

	}

	/**
	 * 
	 * @param bytes
	 * @return 将二进制转换为十六进制字符输出
	 */
	public static String byteToHexString(byte[] bytes) {

		String result = "";
		String hex = "";
		for (int i = 0; i < bytes.length; i++) {
			// 字节高4位
			hex = String.valueOf(hexStr.charAt((bytes[i] & 0xF0) >> 4));
			// 字节低4位
			hex += String.valueOf(hexStr.charAt(bytes[i] & 0x0F));
			result += hex + "";
		}
		return result;
	}

	/**
	 * 
	 * @param hexString
	 * @return 将十六进制转换为字节数组
	 */
	public static byte[] HexStringToBinary(String hexString) {
		// hexString的长度对2取整，作为bytes的长度
		int len = hexString.length() / 2;
		byte[] bytes = new byte[len];
		byte high = 0;// 字节高四位
		byte low = 0;// 字节低四位

		for (int i = 0; i < len; i++) {
			// 右移四位得到高位

			// high = (byte) ((hexStr.indexOf(hexString.charAt(2 * i))) <<
			// 4);//?有问题
			// low = (byte) hexStr.indexOf(hexString.charAt(2 * i + 1));
			// bytes[i] = (byte) (high | low);// 高地位做或运算

			bytes[i] = (byte) Integer.valueOf(
					hexString.substring(2 * i, 2 * i + 2), 16).intValue();
		}
		return bytes;
	}

	/**
	 * @函数功能: BCD码转为10进制串(阿拉伯数据)
	 * @输入参数: BCD码
	 * @输出结果: 10进制串
	 */
	public static String bcd2Str(byte[] bytes) {
		StringBuffer temp = new StringBuffer(bytes.length * 2);

		for (int i = 0; i < bytes.length; i++) {
			temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
			temp.append((byte) (bytes[i] & 0x0f));
		}
		return temp.toString();
		// temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
		// .toString().substring(1) : temp.toString();
	}

	/**
	 * @函数功能: 10进制串转为BCD码
	 * @输入参数: 10进制串
	 * @输出结果: BCD码
	 */
	public static byte[] str2Bcd(String asc) {
		int len = asc.length();
		int mod = len % 2;

		if (mod != 0) {
			asc = "0" + asc;
			len = asc.length();
		}

		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}

		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;

		for (int p = 0; p < asc.length() / 2; p++) {
			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}

			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			} else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}

			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}

	// --------------------------------------------

	private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	public static String toBinaryString(byte b) {
		int u = toUnsigned(b);
		return new String(new char[] { DIGITS[(u >>> 7) & 0x1],
				DIGITS[(u >>> 6) & 0x1], DIGITS[(u >>> 5) & 0x1],
				DIGITS[(u >>> 4) & 0x1], DIGITS[(u >>> 3) & 0x1],
				DIGITS[(u >>> 2) & 0x1], DIGITS[(u >>> 1) & 0x1],
				DIGITS[u & 0x1] });
	}

	public static String toBinaryString(byte... bytes) {
		if (bytes == null)
			return "";
		char[] buffer = new char[bytes.length * 8];
		for (int i = 0, j = 0; i < bytes.length; ++i) {
			int u = toUnsigned(bytes[i]);
			buffer[j++] = DIGITS[(u >>> 7) & 0x1];
			buffer[j++] = DIGITS[(u >>> 6) & 0x1];
			buffer[j++] = DIGITS[(u >>> 5) & 0x1];
			buffer[j++] = DIGITS[(u >>> 4) & 0x1];
			buffer[j++] = DIGITS[(u >>> 3) & 0x1];
			buffer[j++] = DIGITS[(u >>> 2) & 0x1];
			buffer[j++] = DIGITS[(u >>> 1) & 0x1];
			buffer[j++] = DIGITS[u & 0x1];
		}
		return new String(buffer);
	}

	public static String toHexString(byte b) {
		int u = toUnsigned(b);
		return new String(new char[] { DIGITS[u >>> 4], DIGITS[u & 0xf] });
	}

	public static String toHexString(byte... bytes) {
		if (bytes == null)
			return "";
		char[] buffer = new char[bytes.length * 2];
		for (int i = 0, j = 0; i < bytes.length; ++i) {
			int u = toUnsigned(bytes[i]);
			buffer[j++] = DIGITS[u >>> 4];
			buffer[j++] = DIGITS[u & 0xf];
		}
		return new String(buffer);
	}

	public static int toUnsigned(byte b) {
		return b < 0 ? b + 256 : b;
	}

	public static String toStringHex(String s) {
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(
						s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		try {
			s = new String(baKeyword, "utf-8");// UTF-16le:Not
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		String hz = "欢迎";// 迎使用五零四所串口测试系统！

		byte[] bb = new byte[]{(byte)0xFF,(byte)0xff};
		
		System.out
		.println(">>> " + ByteUtil.bytesToShort(bb));
		
		System.out
		.println(">>> " + ByteUtil.byte2ToUnsignedShort(bb));
		 
		System.out
				.println(">>> "
						+ ByteUtil
								.toStringHex("BBB6D3ADCAB9D3C3CEE5C1E3CBC4CBF9B4AEC6B7B2E2CAD4CFB5CDB3A3A1"));

		byte[] xxx = hz.getBytes();

		try {
			System.out.println(">>> " + hz.getBytes("GBK"));

			System.out.println(">>> "
					+ ByteUtil.byteToHexString(hz.getBytes("GB2312")));
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		System.out
				.println("------------------------------------------------------");
		String s = "167E7E0012345678FFFFFF398008020000130220180146059F38";
		s = "0012345678";

		s = "BBB6D3ADCAB9D3C3CEE5C1E3CBC4CBF9B4AEC6B7B2E2CAD4CFB5CDB3A3A1";

		byte[] hexBytes = ByteUtil.HexStringToBinary(s);
		System.out.println(">>> " + ByteUtil.byteToHexString(hexBytes));

		try {
			System.out.println(">>> " + new String(hz.getBytes(), "gbk"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(">>> " + ByteUtil.byteToHexString(hexBytes));
		s = "FFFF";
		hexBytes = ByteUtil.HexStringToBinary(s);
		//
		// String name = "license.dat";
		//
		// System.out.println("license>>>> " +
		// ByteUtil.byteToHexString(name.getBytes()));
		//
		// String name2 = "软件授权已过期，请联系软件提供商进行授权！";
		// System.out.println("tip1>>>>>>> " +
		// ByteUtil.byteToHexString(name2.getBytes()));
		//
		// System.out.println("0x48>>>>>>> "+ ByteUtil.byte2Str(new
		// byte[]{0x48}));
		//
		// byte bytes[] = new byte[] { -1, 0x16 };
		//
		// byte SOH[] = new byte[] { 0x16 };
		// byte eee[] = new byte[] { 0x16 };
		// System.out.println("----------------------"
		// + ByteUtilities.asHex(bytes) + " >>> "
		// + ByteUtil.toHexString(SOH));
		// System.out.println("----------------------" +
		// ByteUtilities.asHex(SOH)
		// + " >>> " + ByteUtil.toBinaryString(SOH));
		//
		// byte a = 0x16;
		// byte b = 0x16;
		// if (a == b) {
		// System.out.println("------ o k  --------");
		// }
		// System.out.println(Integer.toHexString(255));
		//
		// String myvalue = "0012345678"; // 十六进制的数
		//
		// // String myvalue = Integer.toHexString(255);
		//
		// int valueint = Integer.parseInt(myvalue, 16);
		// System.out.println(">>valueint " + valueint);
		//
		// String bivalue = Integer.toBinaryString(valueint);
		// System.out.println(bivalue);
		//
		// byte[] aaa = ubyteToBytes(valueint);
		// System.out.println(">>bytesToUbyte " + bytesToUbyte(aaa));
		// byte[] bbb = ByteUtil.ubyteToBytes(255);
		// System.out.println(">>bbb  bytesToUbyte " +
		// ByteUtil.bytesToUbyte(bbb));
		//
		//
		// int valuebiint = Integer.parseInt(bivalue, 2);
		// System.out.println(Integer.toHexString(valuebiint));
		//
		// String temp = Integer.toHexString(65535);
		// byte[] centerAddr = temp.getBytes();
		// System.out.println(">>bbb  centerAddr " + centerAddr.toString());

		// byte b[] = s.getBytes();
		// int pos = 0;
		// for (int i = 0; i < s.length(); i++) {
		// pos++;
		// System.out.print(s.subSequence(i, i + 1));
		//
		// if (pos == 2) {
		// pos = 0;
		// System.out.print(",0x");
		// }
		// }

	}
}
